package models.weixin;

import jodd.bean.BeanCopy;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import models.constants.DeletedStatus;
import models.constants.Gender;
import models.enums.*;
import models.merchant.Merchant;
import play.Logger;
import play.db.jpa.JPA;
import play.db.jpa.Model;
import shopcart.ShopCart;
import util.common.DateUtil;
import util.common.UStringUtil;
import utils.ObjectUtil;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

/**
 * Created by shancheng on 16-6-17.
 */
@Entity
@Table(name = "power_web_users")
public class WebUser extends Model {

    private static final long serialVersionUID = 289109934185631L;
    public static final String WXMP_CACHEKEY = "WxMpUser2_";

    /**
     * 微信用户名，fromUserName.
     * TODO: 加上索引.
     */
    @Column(name = "openId", length = 50)
    public String openId;


    /**
     * 用户属于哪一个微信号
     */
    @JoinColumn(name = "weixin_data")
    @ManyToOne
    public WeixinData weixinData;


    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "from_type")
    public UserFromType fromType = UserFromType.WEIXIN;


    /**
     * 用户身份  普通用户  商户
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "identity_type")
    public IdentityType identityType = IdentityType.USER;


    /**
     * 认证授权码 本人/本商户 授权码 具有唯一性
     */
    @Column(name = "identity_code")
    public String identityCode;

    /**
     * 介绍人授权码  跟 identityCode 对应
     */
    @Column(name = "introduce_code")
    public String introduceCode;


    /**
     * 上一个介绍人授权码
     * 业务员客户迁移出错，希望迁回时备用
     */
    @Column(name = "old_introduce_code")
    public String oldIntroduceCode;

    /**
     * 客户业务员迁移时间
     * 业务员客户迁移出错，希望迁回时备用
     * 保存迁移时间
     */
    @Column(name = "change_introduce_at")
    public Date changeIntroduceAt;


    /**
     * 修改人ID 最近一次 业务员修改人
     */
    @Column(name = "modify_user_id")
    public Long modifyUserId;


    /**
     * 微信确认身份用
     */
    @Column(name = "uuid")
    public String uuid;


    /**
     * 是否订阅.
     * 用户是否订阅该公众号标识，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
     * 可考虑通过一个定时任务查询当前公众号的用户订阅状态.
     */
    @Column(name = "subcribed")
    public Boolean subcribed;

    /**
     * 用户的昵称
     */
    @Column(name = "nick_name", length = 50)
    public String nickName;


    @Enumerated(EnumType.STRING)
    @Column(name = "sex", length = 10)
    public Gender sex;

    /**
     * 用户语言
     */
    @Column(name = "user_lang", length = 20)
    public String language;


    @Column(name = "city", length = 20)
    public String city;


    /**
     * 领取卡券次数
     */
    @Column(name = "give_coupon_count")
    public Integer giveCouponCount = 0;


    @Column(name = "country", length = 20)
    public String country;


    /**
     * 是否第一次进入
     */
    @Column(name = "is_first")
    public Boolean isFirst;

    /**
     * 用户头像路径.
     * <p/>
     * 保存微信文件到本地.
     */
    @Column(name = "head_img_url", length = 200)
    public String headImgUrl;


    @Column(name = "phone")
    public String phone;

    @Column(name = "birthDay")
    public String birthDay;

    @Column(name = "sign")
    public String sign;

    /**
     * 用户注册时间.
     * 用户注册时间
     */
    @Column(name = "created_at")
    public Date createAt;

    /**
     * 抽奖机会
     */
    @Column(name = "prize_chance")
    public Integer prizechance = 0;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "deleted")
    public DeletedStatus deleted = DeletedStatus.UN_DELETED;

    /**
     * 用户等级 优质 , 普通 , 休眠 , 其他用户
     * SENIOR // 优质客户
     * ,ORDINARY // 普通客户
     * ,DORMANCY // 休眠用户
     * ,OTHER // 其他用户
     * 默认等级为休眠用户
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "user_level")
    public UserLevel userLevel = UserLevel.DORMANCY;

    /**
     * 客户分类:
     * NORMAL  正常用户
     * ,EMPLOYEE  内部员工
     * ,CLOSEDSHOP  关门搬迁客户
     * 默认正常用户
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "user_classify")
    public UserClassify userClassify = UserClassify.NORMAL;

    /**
     * 客户属性 , 客户身份
     * RETAILERSUPER 零售商超 ,
     * CATERING 餐饮业 ,
     * SCHOOLENTERPRISE 校企单位 ,
     * OTHER 其他
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "user_attribute")
    public UserAttribute userAttribute;


    /**
     * 积分
     */
    @Column(name = "integrals")
    public Integer integrals = 0;

    /**
     * 账户余额
     */
    @Column(name = "balance" ,columnDefinition = "decimal(15,2)")
    public Double balance= 0d;


    /**
     * 备注
     */
    @Column(name = "remark")
    public String remark;

    /**
     * 按weixinUser值更新指定ID的WeixinUser.
     */
    public static void update(Long id, WebUser weixinUser) {
        WebUser oldWeixinUser = WebUser.findById(id);
        BeanCopy.beans(weixinUser, oldWeixinUser).ignoreNulls(true).copy();
        oldWeixinUser.save();
    }

    /**
     * 删除指定ID的WeixinMenu
     */
    public static void delete(Long id) {
        WebUser weixinUser = WebUser.findById(id);
        weixinUser.deleted = DeletedStatus.DELETED;
        weixinUser.save();
    }

    /**
     * 根据OpenId查询用户
     */
    public static WebUser findByOpenId(String openId) {
        return WebUser.find("openId = ? and deleted = ?", openId, DeletedStatus.UN_DELETED).first();
    }

    /**
     * 查询出商户指定OpenId的用户.
     */
    public static WebUser findOrCreateMerchantWxUser(Merchant merchant, WxMpUser wxMpUser, String dcode) {
        WebUser webUser = WebUser.find("weixinData = ? and openId=? and deleted = ?", merchant.weixinData, wxMpUser.getOpenId(), DeletedStatus.UN_DELETED).first();
        if (webUser == null) {
            webUser = new WebUser();
            webUser.createAt = new Date();
            webUser.deleted = DeletedStatus.UN_DELETED;
            webUser.weixinData = merchant.weixinData;
            webUser.openId = wxMpUser.getOpenId();
            webUser.nickName = wxMpUser.getNickname();
            webUser.subcribed = Boolean.FALSE;
            webUser.introduceCode = dcode;
            webUser.city = wxMpUser.getCity();
            webUser.country = wxMpUser.getCountry();
            webUser.language = wxMpUser.getLanguage();
            webUser.headImgUrl = wxMpUser.getHeadImgUrl();
            webUser.isFirst = true;
            if ("1".equals(wxMpUser.getSex()) || "男".equals(wxMpUser.getSex())) {
                webUser.sex = Gender.MALE;
            } else if ("2".equals(wxMpUser.getSex()) || "女".equals(wxMpUser.getSex())) {
                webUser.sex = Gender.FEMALE;
            } else {
                webUser.sex = Gender.UNKNOWN;
            }
            webUser.subcribed = wxMpUser.isSubscribe();
            webUser.save();
        }
        webUser.identityCode = ObjectUtil.coverNumber(webUser.id.intValue(), 6);
        webUser.save();
        return webUser;
    }

    public static List<WebUser> findAvailable() {
        return WebUser.find("deleted = ?", DeletedStatus.UN_DELETED).fetch();
    }

    public Long shopCount(Long merchantId) {
        return ShopCart.findShopCartSize(this, merchantId);
    }

    /**
     * 根据授权码查询用户
     *
     * @param identityCode
     * @return
     */
    public static WebUser findByIdentityCode(String identityCode) {
        return WebUser.find("identityCode = ? and deleted = ?", identityCode, DeletedStatus.UN_DELETED).first();
    }

    public static WebUser findByUserId(long id) {
        return WebUser.find(" id = ? and deleted = ?", id, DeletedStatus.UN_DELETED).first();
    }


    public static WebUser findByUUid(String uuid) {
        return WebUser.find("uuid = ? and deleted = ?", uuid, DeletedStatus.UN_DELETED).first();
    }

    public static List<WebUser> findBYWeiXinDataId(Long merchantId) {
        Merchant merchant = Merchant.findByMerchantId(merchantId);
        return WebUser.find("deleted = ? and weixinData.id = ?", DeletedStatus.UN_DELETED, merchant.weixinData.id).fetch();
    }

    /**
     * 更新用户的抽奖次数
     *
     * @param weixinDataId
     * @param prizechance
     */
    public static void resetPrizeChance(long weixinDataId, int prizechance) {
        String sqlSelect = " update power_web_users a set a.prize_chance = " + prizechance + " where a.weixin_data = " + weixinDataId + " and a.deleted = 0";
        JPA.em().createNativeQuery(sqlSelect).executeUpdate();
        Logger.info(" LOGGER 2017041700008 updateUserPrizeChance weixinData:%s 已更新抽奖次数:%s", weixinDataId, prizechance);

    }


    /**
     * 将某业务员名下的客户转移到另外一业务员名下
     * 方法:更改客户介绍人授权码(introduceCode),
     * 将客户的介绍人授权码(introduceCode),更改为另一业务员的授权码(identityCode)
     *
     * @param fromIdentityCode
     * @param toIdentityCode
     */
    public static void transferCustoms(String fromIdentityCode, String toIdentityCode, long modifyUserId) {

        String updateSql = "update power_web_users a set a.change_introduce_at = now(),  a.old_introduce_code = a.introduce_code , a.modify_user_id =" + modifyUserId + " ,  a.introduce_code = '" + toIdentityCode + "' where a.introduce_code = '" + fromIdentityCode + "'";
        JPA.em().createNativeQuery(updateSql).executeUpdate();

    }

    /**
     * 批量更换客户的业务人员
     *
     * @param introduceCode
     * @param webUserIds
     */
    public static void replaceIntroduceCode(String introduceCode, Long[] webUserIds, long operateUserId) {
        String ids = UStringUtil.concatStr(",", webUserIds);
        String updateSql = " update power_web_users a set a.change_introduce_at = now(), a.old_introduce_code = a.introduce_code , a.introduce_code = '" + introduceCode + "' ,a.modify_user_id = " + operateUserId + " where a.id in(" + ids + ");";
        JPA.em().createNativeQuery(updateSql).executeUpdate();

    }


    /**
     * 查询某业务员下的所有客户
     * @param introduceCode
     * @return
     */
    public static List<WebUser> loadByIntroduceCode(String introduceCode){
        return  WebUser.find("deleted = ?1 and introduceCode = ?2" , DeletedStatus.UN_DELETED , introduceCode).fetch();
    }

    /**
     * 查询某一类用户
     * @param classify
     * @param weixinId
     * @return
     */
    public static List<WebUser> loadByDeletedAndClassify(UserClassify classify  , long weixinId){
        return WebUser.find("deleted = ?1 and userClassify = ?2 and weixinData.id = ?3" , DeletedStatus.UN_DELETED , classify , weixinId).fetch();
    }


}
